/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.tarea1;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

/**
 *
 * @author jorgeorm
 */
public class GeneradorStandarMinimo implements GeneradorNumeros{
    private String archivoSalida="salidaGenerStandMinimo.txt";
    private Integer numeroDatos=0;
    private Double modulo, semilla, factorA, factorQ, factorR;
    private Double [] numsAleatorios, numsNormalizados;
    private Random generadorAleat;

    public List<Double> getNumsNormalizados() {
        List<Double> retorno= new ArrayList<>(Arrays.asList(numsNormalizados));
        return retorno;
    }
//
//    public void setNumsNormalizados(List<Double> listaNums) {
//        this.numsNormalizados = numsNormalizados;
//    }
//    
    public GeneradorStandarMinimo(int numeritoDatos){
        generadorAleat= new Random(System.currentTimeMillis());
//        do{
//            numeroDatos=generadorAleat.nextInt(10000);
//        }while (numeroDatos<100);
        this.numeroDatos= numeritoDatos;
        numsAleatorios= new Double[numeroDatos];
        numsNormalizados= new Double[numeroDatos];
        
        generarNumeros();
    }    
    /*Requiere el nùmero de datos pseudoaleatorios a generar
     */
    public GeneradorStandarMinimo(int n_datos, int valorModulo, int valorA,int semilla){
        numeroDatos=n_datos;
        numsAleatorios= new Double[n_datos];
        numsNormalizados= new Double[n_datos];
        
        generarNumeros(semilla,valorModulo, valorA);
    }

    @Override
    public void generarNumeros() {
        Integer valorA= generadorAleat.nextInt(10000);
        if(valorA<0) {
            valorA= valorA*(-1);
        }
        
        int semillita= (int) System.currentTimeMillis();
        
        generarNumeros(semillita, 
                Integer.MAX_VALUE,
                valorA);
    }
    
    public void generarNumeros(int semilla, int modulo,int valorA) {
        this.semilla=(double)semilla;
        this.factorA=(double)valorA;
        this.modulo=(double)modulo;
        
        factorQ=Math.floor(modulo/factorA);
        factorR=modulo % factorA;
        
        double xAnterior=semilla;
        double calcParcial=0;
        
        //Lleno el array de nùmeros aleatorios
        
        for (int i = 0; i < numsAleatorios.length; i++) {
            calcParcial=xAnterior % factorQ;
            calcParcial=factorA*calcParcial;
            calcParcial=calcParcial-(factorR*Math.floor(xAnterior/factorQ));
//            calcParcial=(factorA*(xAnterior % factorQ))-(factorR*Math.floor(xAnterior/factorQ));
            if(calcParcial<0){
                calcParcial=calcParcial+modulo;
            }
            
            numsAleatorios[i]=calcParcial;
            numsNormalizados[i]=calcParcial/modulo;
            
            xAnterior=calcParcial;
            calcParcial=0;
        }
    }

    @Override
    public void escribirSalida() {
        //TODO:Hacer la escritura a archivos para las gráficas
        System.out.println("Numeros Aleatorios generados con Standar Mìnimo!:");
        System.out.printf("modulo:%.1f, semilla:%.1f, factorA:%.1f, factorQ:%.1f, factorR:%.1f\n",modulo, semilla, factorA, factorQ, factorR);
        System.out.println("Numero Aleatorio,\tNumero Normalizado");
        for (int i = 0; i < numsAleatorios.length; i++) {
            System.out.printf("%15.1f,\t%.17f\n", numsAleatorios[i],numsNormalizados[i]);
        }
    }

    public Double getModulo() {
        return modulo;
    }

    public Double getSemilla() {
        return semilla;
    }

    public Double getFactorA() {
        return factorA;
    }

    public Double getFactorQ() {
        return factorQ;
    }

    public Double getFactorR() {
        return factorR;
    }

    
    
    
}
